#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/1/1 16:04
# @Author : George
"""
在 Selenium 4 中，不再直接在 webself.driver.Chrome 中设置驱动程序路径，而是通过引入 Service 对象来设置。
这样可以避免弃用警告，并确保驱动程序的正确加载
"""
import os.path

from selenium import webdriver
from selenium.webdriver.edge.service import Service as EdgeService
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import time
from lxml import etree
import requests
import chardet
import json
from log_test import logger


class VideoAutoPlay(object):
    def __init__(self):
        self.driver = {}
        self.count_num = 1
        self.movies_dict = None
        self.home_url = "https://www.agedm.org/"
        self.headers = {
            "Referer": "https://www.agedm.org/",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"
        }

    def get_html_tree(self, url: str) -> etree._Element:
        """获取页面HTML并返回etree对象"""
        response = requests.get(url, headers=self.headers)
        if response.status_code != 200:
            raise Exception(f"Failed to get {url}, status code: {response.status_code}")

        encoding = chardet.detect(response.content)['encoding']
        response.encoding = encoding
        return etree.HTML(response.text)

    def movies_input(self, movie_name, n):
        try:
            if not self.driver:
                self.driver = self.setup_driver()

            self.driver.get(self.home_url)
            # 查找搜索框元素
            search_box = self.driver.find_element(By.ID, "query")

            # 输入搜索内容
            search_box.send_keys(movie_name)

            # 提交搜索表单
            search_box.send_keys(Keys.RETURN)

            # 等待搜索结果加载
            # WebDriverWait(self.driver, 10).until(
            #     EC.presence_of_element_located((By.CLASS_NAME, "content_left"))
            # )
            # 二级请求
            self.driver.get(f"https://www.agedm.org/search?query={movie_name}")

            # 查找在线播放btn
            # wait = WebDriverWait(self.driver, 10)  # 10秒超时
            # # titles = home_tree.xpath("//*[@class='sonspic']/div[1]/p[1]/a[1]/b/text()")
            button = self.driver.find_element(By.XPATH, "//*[@class='video_btns']/a[1]")
            # print(button)
            button.click()
            WebDriverWait(self.driver, 30).until(
                EC.presence_of_element_located((By.CLASS_NAME, "tab-content"))
            )
            # # 等待搜索结果加载
            detail_url = self.driver.current_url
            tree = self.get_html_tree(detail_url)
            url_dict = {}
            titles = tree.xpath("//*[@class='video_detail_episode']/li/a/text()")[n - 1:]
            urls = tree.xpath("//*[@class='video_detail_episode']/li/a/@href")[n - 1:]
            for title, url in zip(titles, urls):
                url_dict[title] = url
            # print(url_dict)
            return url_dict
        except Exception as e:
            logger.error(f"搜索过程发生错误: {str(e)}")
            if self.driver:
                self.driver.quit()
                self.driver = None
            return {}

    def setup_driver(self):
        # 优化视频播放性能的设置
        options = webdriver.EdgeOptions()
        options.add_argument('--disable-gpu')  # 禁用GPU加速
        options.add_argument('--no-sandbox')  # 禁用沙箱模式
        options.add_argument('--disable-dev-shm-usage')  # 禁用/dev/shm使用
        options.add_argument('--disable-software-rasterizer')  # 禁用软件光栅化
        options.add_argument('--disable-extensions')  # 禁用扩展
        options.add_argument('--disable-infobars')  # 禁用信息栏
        options.add_argument('--autoplay-policy=no-user-gesture-required')  # 允许自动播放
        options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 禁用自动化提示
        options.add_experimental_option("useAutomationExtension", False)  # 禁用自动化扩展

        # 设置正确的驱动路径
        service = EdgeService(executable_path='./msedgedriver.exe')
        return webdriver.Edge(options=options, service=service)

    def video_player(self, movie_name, n, current_time):
        try:
            url_dict = self.movies_input(movie_name, n)
            if not url_dict:
                logger.error("未找到可播放的视频链接")
                return

            if not self.driver:
                self.driver = self.setup_driver()

            for title, url in url_dict.items():
                try:
                    # 打开网站
                    self.driver.get(url)
                    # 切换到视频iframe
                    self.driver.switch_to.frame("iframeForVideo")
                    logger.info(f"开始时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")

                    # 等待视频元素加载
                    wait = WebDriverWait(self.driver, 20)
                    video_element = wait.until(
                        EC.presence_of_element_located((By.CLASS_NAME, "art-video"))
                    )
                    logger.info(f"找到视频元素: {video_element}")
                    logger.info(f"{movie_name}:{title}集开始播放".center(10, "="))

                    # 等待视频加载完成后执行全屏
                    page_stage = True
                    while page_stage:
                        paused_state = self.driver.execute_script("return arguments[0].paused;", video_element)
                        print("paused_state", paused_state)
                        if not paused_state:
                            break
                    # 获取视频时长
                    duration = self.driver.execute_script("return arguments[0].duration", video_element)
                    logger.info(f"视频时长: {int(duration // 60)}分{int(duration % 60)}秒")
                    # 双击使得视频全屏显示
                    ActionChains(self.driver).double_click(video_element).perform()
                    time.sleep(3)
                    # 设置视频开始播放时间
                    self.driver.execute_script("arguments[0].currentTime = arguments[1];", video_element,
                                               current_time)
                    # 视频单击播放
                    paused_state = self.driver.execute_script("return arguments[0].paused;", video_element)
                    if paused_state:
                        logger.info(f"{movie_name}:{title}触发双击全屏")
                        ActionChains(self.driver).click(video_element).perform()

                    # # 点击视频开始播放
                    # action = ActionChains(self.driver)
                    # action.move_to_element_with_offset(video_element, 100, 100).click().perform()
                    # print(f"点击播放时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
                    """
                    
                        currentTime: 15.089264
                        15s
                        duration: 1420.094671
                        23:40 ,23*60+40 => 1420
                    """
                    # 等待视频播放完成
                    current_time_new = 0
                    for i in range(1, int(duration) - current_time +1):
                        time.sleep(1)
                        current_time_new += 1
                        # logger.info(f"当前播放时长: {int(current_time_new // 60)}分{int(current_time_new % 60)}秒")
                        paused_state = self.driver.execute_script("return arguments[0].paused;", video_element)
                        if paused_state:
                            break
                    logger.info(f"时间：{current_time_new},{int(duration) - current_time},{int(duration)}")
                    if paused_state and current_time_new < int(duration)-current_time:
                        current_time = current_time+current_time_new
                        self.update_movie_count(movie_name, n, current_time)
                        logger.info(
                            f"第{title}集播放被打断，播放至{int(current_time // 60)}分{int(current_time % 60)}秒".center(
                                10, "="))
                    else:
                        n = n + 1
                        # current_time_new = 0
                        current_time = 0 # 测试开始时间重置为0
                        self.update_movie_count(movie_name, n, current_time)
                        logger.info(f"第{title}集播放完毕".center(10, "="))


                except Exception as e:
                    logger.error(f"播放第{title}集时发生错误: {str(e)}")
                    continue

        except Exception as e:
            logger.error(f"视频播放总体发生错误: {str(e)}")
        finally:
            if self.driver:
                self.driver.quit()
                self.driver = None

    def __del__(self):
        """确保在对象销毁时关闭driver"""
        if self.driver:
            try:
                self.driver.quit()
            except:
                pass

    def count_read(self, movies, n=1, start_time=1):
        # 将此文件作为播放内容的缓存
        if not os.path.exists("./count.json"):
            with open("./count.json", "w", encoding="utf-8") as f:
                self.movies_dict = {movies: [n, start_time]}
                json.dump(self.movies_dict, f, ensure_ascii=False)
            return n, start_time
        else:
            with open("./count.json", "r", encoding="utf-8") as f:
                self.movies_dict = json.load(f)
            if not self.movies_dict.get(str(movies)):  # 读取不到movies
                self.movies_dict.update({str(movies): [n, start_time]})
                with open("./count.json", "w", encoding="utf-8") as f:
                    json.dump(self.movies_dict, f, ensure_ascii=False)
                return n, start_time
            else:  # 读取到了movie
                self.count_num, current_time = self.movies_dict[str(movies)]
                return self.count_num, current_time

    # update movies count
    def update_movie_count(self, movies, n, current_time):
        with open("./count.json", "w", encoding="utf-8") as f:
            self.movies_dict[str(movies)] = [n, current_time]
            json.dump(self.movies_dict, f, ensure_ascii=False)


if __name__ == "__main__":
    video = VideoAutoPlay()
    movie = "火影忍者 疾风传"
    # movie = "神之塔 第二季"
    count_num, start_time = video.count_read(movie, 1, 1)
    # video.update_movie_count(movie, 4)
    video.video_player(movie, count_num, start_time)
